Specs2で嵌っていた話


概要

Scalaでマルチスレッド的なアプリケーションを作っていた。

テストしつつ。


で、今回はSpecs2を使ってるので、


"testCollection" should in {

"test1" in {

...

}


"test2" in {

...

}


"test3" in {

...

}

}


みたいに書いてた。



事象

あるテストを、バリエーション含めて3件書いていた時、

各テストの有無によって結果が変わる。

まーきっと自分たちのバグだろーと思ってまとめつつ、下記のようにケースを書き出した。


テストしていた対象は、

Actorを内包したクラスで、タイムアウトを指定/指定せず動作

・テストケースではwaitをかけて、起動→動作が終わったかなーっていう時間まで待つ→待機解いてチェック

ということを行っていた。



1 タイムアウト無し

2 タイムアウトあり時間内に終了

で問題が出る?→違った



1 タイムアウト無し

3 タイムアウトあり

で問題がでる?→違った



1 タイムアウト無し

2 タイムアウトあり時間内に終了

+

3 タイムアウトあり

で1,2がRunningで停まる(1,3だったり、2,3だったりランダムな事があとで判明する)



ただ単に時間がかかる系?違うな。必ず、ってのがおかしい。

内容について調べてみると、別インスタンスのはずの、各テストケースのクラス中のvarが更新されてしまう、というのが原因だった

なんでこんな事が?



最終的に

→Threadの止め方の問題だった。

Specs2は、非同期のテストを書きたい場合は、そのまま、


Thread.sleep(long) 


で、待てば良いのだった。


このへん、待つ機能を独自に作って使い回してたのが判明(Actor側に同期通信投げてActor内でThread.sleep)

穴を掘って穴に嵌った形。

値が同期したのは、単純に「システムの一部がロックして、値が変わらなかった」のを誤って観測したため。

お粗末!